package com.bby.disk.service.impl;

import cn.hutool.core.io.FileUtil;
import com.bby.common.config.GlobalSettings;
import com.bby.common.exception.BBYException;
import com.bby.common.utils.R;
import com.bby.common.utils.StatusCode;
import com.bby.disk.bean.req.ThumbnailReq;
import com.bby.disk.exception.BBYExceptionHandler;
import com.bby.disk.manager.auth.AuthorityManager;
import com.bby.disk.manager.download.DirectLinkObj;
import com.bby.disk.manager.download.DirectLinkResult;
import com.bby.disk.manager.download.DownloadManager;
import com.bby.disk.manager.virtual.*;
import com.bby.disk.service.IDownloadService;
import com.bby.disk.util.BBYFileSystem;
import com.bby.disk.util.VideoImgUtil;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class DownloadService implements IDownloadService {


    public DownloadService(DownloadManager downloadManager) {
        this.downloadManager = downloadManager;
    }

    DownloadManager downloadManager;

    @Override
    public DirectLinkResult createDirectLink(String userId, String target) throws BBYException {
        VirtualObject virtualFile = AuthorityManager.download(userId, target);
        if (!virtualFile.isFile()) {
            throw new BBYException(StatusCode.NOT_FOUND,"目标是一个目录！");
        }
        DirectLinkObj result = downloadManager.createDirectLink((VirtualFile) virtualFile);
        return new DirectLinkResult(virtualFile.getId(), result.getId());
    }

    @Override
    public Map<String, DirectLinkResult> createDirectLinks(String userId, List<String> fileList) throws BBYException {
        List<VirtualFile> files = new ArrayList<>();
        Map<String, DirectLinkResult> resultMap = new HashMap<>();

        for (String id : fileList) {
            try {
                VirtualObject file = AuthorityManager.download(userId, id);
                if (file.isFile()) {
                    files.add((VirtualFile) file);
                }
            } catch (BBYException ex) {
                resultMap.put(id, new DirectLinkResult(id, ex.getCode(), ex.getMessage()));
            }
        }
        downloadManager.createDirectLinks(files).forEach((k, v) -> resultMap.put(k, new DirectLinkResult(k, v)));
        return resultMap;
    }

    @Override
    public Map<String, DirectLinkResult> createVideoImg(String userId, List<String> targets) {
        Map<String, DirectLinkResult> map = new HashMap<>();
        for (String id : targets) {
            DirectLinkResult result;
            try {
                VirtualObject file = AuthorityManager.download(userId, id);
                if (file.isFile()) {
                    if (VideoImgUtil.isVideo(file.getName())) {
                        result = new DirectLinkResult(id, downloadManager.createVideoImg((VirtualFile) file).getId());
                    } else {//开始生成
                        result = new DirectLinkResult(id, StatusCode.FILE_ERROR, "文件格式不支持！");
                    }
                } else {
                    result = new DirectLinkResult(id, StatusCode.NOT_FOUND, "文件是目录！");
                }
            } catch (BBYException ex) {
                result = new DirectLinkResult(id, ex.getCode(), ex.getMessage());
            }
            map.put(id, result);
        }
        return map;
    }

    @Override
    public void imgView(ThumbnailReq req) throws Exception {
        ServletRequestAttributes attributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
        if (attributes == null) {
            throw BBYExceptionHandler.INPUT_ERROR_EX;
        }
        HttpServletResponse response = attributes.getResponse();
        if (response == null) {
            throw BBYExceptionHandler.INPUT_ERROR_EX;
        }
        downloadManager.imgView(req, response);
    }
    @Override
    public void viewVideoImg(String fileId, String directId) throws BBYException {
        ServletRequestAttributes attributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
        assert attributes != null;
        HttpServletResponse response = attributes.getResponse();
        downloadManager.viewVideoImg(fileId,directId, response);
    }

    @Override
    public void getAvatar(String avatar, HttpServletResponse response) {
        File file = BBYFileSystem.get(avatar);
        if (!file.exists()){
            return;
        }
        try {
            FileUtil.writeToStream(file,response.getOutputStream());
            response.setContentType("image/*");
        } catch (IOException e) {
            response.setStatus(500);
        }
    }

    @Override
    public void download(String fileId, String directId) throws Exception {
        ServletRequestAttributes attributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
        if (attributes == null) {
            throw BBYExceptionHandler.INPUT_ERROR_EX;
        }
        HttpServletResponse response = attributes.getResponse();
        if (response == null) {
            throw BBYExceptionHandler.INPUT_ERROR_EX;
        }
        String range = attributes.getRequest().getHeader("range");
        downloadManager.download(fileId, directId, range, response);
    }

    @Override
    public void video(String fileId, String directId) throws BBYException {
        ServletRequestAttributes attributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
        if (attributes == null) {
            throw BBYExceptionHandler.INPUT_ERROR_EX;
        }
        HttpServletResponse response = attributes.getResponse();
        String range = attributes.getRequest().getHeader("range");
        if (response == null) {
            throw BBYExceptionHandler.INPUT_ERROR_EX;
        }
        downloadManager.video(fileId, directId, range, response);
    }

}
